/* Copyright (c) 2004-2022 peigen.info. All rights reserved. */

package info.peigen.hotpot.common.core.lang;

import info.peigen.hotpot.common.core.annotation.Comment;
import info.peigen.hotpot.common.core.enums.ElectricUnit;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import lombok.experimental.Accessors;
import lombok.experimental.FieldDefaults;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;
import java.math.BigDecimal;

/**
 * <b>(Electricity)</b>
 * 电量
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2022/6/17
 */
@SuperBuilder
@Data
@NoArgsConstructor
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
@Accessors(chain = true)
public class Electricity implements Serializable, Comparable<Object> {
    @Comment(value = "电量值")
    BigDecimal value;

    @Comment(value = "电量单位")
    @Builder.Default
    ElectricUnit electricUnit = ElectricUnit.KW_H;

    public static Electricity zero() {
        return new Electricity();
    }

    /**
     * 断言本电量对象与另一电量对象是否具有相同的电量单位。
     *
     * <p>
     * 如果本电量对象与另一电量对象具有相同的电量单位，则方法返回。 否则抛出运行时异常
     * <code>java.lang.IllegalArgumentException</code>。
     *
     * @param other 另一电量对象
     *
     * @throws IllegalArgumentException 如果本电量对象与另一电量对象电量单位不同。
     */
    protected void assertSameElectricUnitAs(Electricity other) {
        if (!electricUnit.equals(other.electricUnit)) {
            throw new IllegalArgumentException("Electricity math electricUnit mismatch.");
        }
    }

    /**
     * 电量比较。
     *
     * <p>
     * 比较本电量对象与另一电量对象的大小。 如果待比较的两个电量对象的电量单位不同，则抛出
     * <code>java.lang.IllegalArgumentException</code>。
     * 如果本电量对象的数值少于待比较电量对象，则返回-1。 如果本电量对象的数值等于待比较电量对象，则返回0。
     * 如果本电量对象的数值大于待比较电量对象，则返回1。
     *
     * @param other 另一对象。
     *
     * @return -1表示小于，0表示等于，1表示大于。
     *
     * @throws IllegalArgumentException 待比较电量对象与本电量对象的电量单位不同。
     */
    public int compareTo(Electricity other) {
        assertSameElectricUnitAs(other);
        return value.compareTo(other.value);
    }

    @Override
    public int compareTo(@NotNull Object o) {
        return compareTo((Electricity) o);
    }
}